﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KnBinarySerializer.Data
{
    internal class DataTableFormatter : IFormatter
    {       
        public Type GetHandleType()
        {
            return typeof(DataTable);
        }

        public byte GetKey()
        {
            return 32;
        }
        public bool IsFixLen()
        {
            return false;
        }
        public object ReadBytes(BinarySerializeManager content, int maxLen, Type type)
        {
            DataTable dt = new DataTable();
            //long start = content.GetPosition();
            dt.TableName = (string)content.DeSerializeObject(typeof(string));
            //读取个数
            int colCnt = content.ReadInt();
            //position += 4;
            //创建字段
            for (int i = 0; i < colCnt; i++)
            {
                //字段类型key
                byte key = content.ReadByte();
                //byte nameKey = content.ReadByte();
                //int nameLen = content.ReadInt();               
                //IFormatter formatter = FormatterFactory.GetFormatter(nameKey);                
                //string fieldName = (string)formatter.ReadBytes(content,nameLen, null);
                string fieldName = content.DeSerializeObject<string>();
                //字段类型
                IFormatter colFormatter = content.GetFormatter(key);
                dt.Columns.Add(fieldName, colFormatter.GetHandleType());
            }
            int rowCnt = content.ReadInt();
            //读取内容
            for(int rowIndex=0;rowIndex< rowCnt;rowIndex++)
            {
                DataRow row = dt.NewRow();
                //读取行状态
                byte status = content.ReadByte();
                for (int i = 0; i < colCnt; i++)
                {
                    byte key = content.ReadByte();
                    //不能使用conent的反序列化方法。此处有可能获得的类型是object等无意义的类型
                    IFormatter formatter = content.GetFormatter(key);                    
                    object obj = formatter.ReadBytes(content, -1, null);
                    row[i] = obj;
                }
                dt.Rows.Add(row);
                row.AcceptChanges();
                switch ((DataRowState)status)
                {
                    case DataRowState.Added:
                        row.SetAdded();
                        break;
                    case DataRowState.Deleted:
                        row.Delete();
                        break;
                    case DataRowState.Modified:
                        row.SetModified();
                        break;
                }
            }
            return dt;
        }

        public int WriteBytes(BinarySerializeManager serial, object obj)
        {
            //long start = serial.GetPosition();
            DataTable table = (DataTable)obj;
            //写入tableName
            serial.SerializeObject(table.TableName);

            //byte[] colCnt = RRQMBitConverter.Default.GetBytes(table.Columns.Count);
            //serial.Write(colCnt);
            //写入列数量
            serial.Write(table.Columns.Count);
            Dictionary<string, IFormatter> formaters = new Dictionary<string, IFormatter>();
            //写入字段内容
            foreach (DataColumn dataColumn in table.Columns)
            {
                //利用序列器保存创建列的类型
                IFormatter formatter = serial.GetFormatter(dataColumn.DataType);
                formaters.Add(dataColumn.ColumnName, formatter);
                byte key = formatter.GetKey();
                serial.Write(key);
                //写入字段名
                serial.SerializeObject(dataColumn.ColumnName);
            }
            //写入行数量
            serial.Write(table.Rows.Count);
            //写入每行内容
            foreach (DataRow row in table.Rows)
            {
                //写入行状态
                byte status = (byte)row.RowState;
                serial.Write(status);
                foreach (DataColumn dataColumn in table.Columns)
                {
                    object cell = null;
                    if (row.RowState == DataRowState.Deleted)
                        cell = row[dataColumn.ColumnName, DataRowVersion.Original];
                    else
                        cell = row[dataColumn.ColumnName];
                    if (cell == null)//DBNull.Value由None.DBNullFormatter处理
                    {
                        IFormatter formatter = formaters[dataColumn.ColumnName];//null无法通过对象获取序列器号，必须通过字段名来获取。
                        serial.WriteNull(formatter);
                    }
                    else
                    {
                        //如果列的值被放入一个DataRow，会是一个难以预想的情况，在此限制只支持基准类型，不支持自定类，所以不允许ClassFormatter
                        IFormatter formatter = serial.GetFormatter(cell);//按内容获取格式化，列类型为object的不支持ClassFormatter;
                        if (formatter.GetKey() == 0)
                            throw new KnBinaryException(this.GetKey(), $"单元格的类型{cell.GetType().Name}在DataTable中无法序列化");
                        serial.SerializeObject(cell);                        
                    }
                }
            }
            //return serial.GetLength(start);
            return -1;
        }

    }
}
